//
//  ViewController.m
//  常驻线程
//
//  Created by Hello Cai on 2020/1/31.
//  Copyright © 2020 Hello Cai. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, assign) BOOL finished;
@property (nonatomic, strong) NSThread *thread;
@property (nonatomic, strong) NSTimer *timer;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
//    [self runloopPort];
    
    [self runloopTimer];
}

-(void)runloopPort{
    __weak typeof(self) weakSelf =self;
    self.thread = [[NSThread alloc] initWithBlock:^{
        
        //添加端口
        [[NSRunLoop currentRunLoop] addPort:[NSMachPort port] forMode: NSDefaultRunLoopMode];
        
        //runloop跑循环，子线程就能不死（调用run这种方式跑循环，runloop无法退出）
        [[NSRunLoop currentRunLoop] run];
        
        NSLog(@"任务结束了");
    }];
    [self.thread start];
}

-(void)runloopTimer{
    //常驻线程中添加可执行任务的案例（此常驻线程无法退出）
    [self threadTimerDemo1];
    
    //常驻线程中添加可执行任务的案例（此常驻线程能有条件退出）
//    [self threadTimerDemo2];
    
    //立即结束常驻线程的案例
//    [self threadTimerDemo3];
}

-(void)threadTimerDemo1{
    /* 子线程中创建定时器执行任务例子
     thread声明为属性是没用的，因为声明只能让oc对象self.thread活着，但底层的线程还是死了。
     子线程一般执行完任务就会销毁，要想线程不死，必须有执行不完的任务。这里涉及到三个知识点：
     1.子线程的runloop默认不开启，需要手动开启它
     2.runloop开启后要想持续跑圈而不退出，必须往里面添加Port或定时器
     3.开启runloop，类似添加了个do while循环，这个线程会一直卡在do while循环中，这样线程的任务一直没有执行完，就能让线程不死.
     */
    __weak typeof(self) weakSelf =self;
    self.thread = [[NSThread alloc] initWithBlock:^{
        
        NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerGo) userInfo:nil repeats:YES];
        // runloop中添加定时器
        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
        weakSelf.timer = timer;
        
        //runloop跑循环，子线程就能不死（调用run这种方式跑循环，runloop无法退出）
        [[NSRunLoop currentRunLoop] run];
        
        NSLog(@"任务结束了");
    }];
    [self.thread start];
}

-(void)threadTimerDemo2{
    __weak typeof(self) weakSelf =self;
    self.thread = [[NSThread alloc] initWithBlock:^{
        
        NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerGo) userInfo:nil repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
        weakSelf.timer = timer;
        
        /*
         直接用runMode:beforeDate:开启runloop，往该子线程添加任一任务，任务执行完后，runloop会退出。
         以下方式能够有条件的退出
         */
        
        int i=0;
        while (!weakSelf.finished) {
            NSLog(@"第%d个循环", ++i);
            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
        }
        
        NSLog(@"任务结束了");
    }];
    [self.thread start];
}

-(void)threadTimerDemo3{
    __weak typeof(self) weakSelf =self;
    self.thread = [[NSThread alloc] initWithBlock:^{
        
        NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerGo) userInfo:nil repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
        weakSelf.timer = timer;
        
        //用这种方式开启runloop，当往线程中添加任意任务，任务执行完后runloop会退出
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
        
        NSLog(@"任务结束了");
    }];
    [self.thread start];
}



-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [super touchesBegan:touches withEvent:event];
    
//    [self portTask];
 
    [self timerTask];
}

-(void)portTask{
    [self performSelector:@selector(addExcuteTask1) onThread:self.thread withObject:nil waitUntilDone:NO];
}

-(void)timerTask{
    //threadDemo1
    [self performSelector:@selector(addExcuteTask1) onThread:self.thread withObject:nil waitUntilDone:NO];
    
    //threadDemo2
//    [self performSelector:@selector(addExcuteTask2) onThread:self.thread withObject:nil waitUntilDone:NO];
    
    //threadDemo3
//    [self performSelector:@selector(anyTask) onThread:self.thread withObject:nil waitUntilDone:NO];
}

-(void)timerGo{
    NSLog(@"timer来了,%@",[NSThread currentThread]);
}

//这是一个可执行任务1
-(void)addExcuteTask1{
    NSLog(@"Hi, 这是往常驻线程额外添加的任务");
    NSLog(@"%@", [NSRunLoop currentRunLoop]);
}

//这是一个可执行任务2
-(void)addExcuteTask2{
    static int i=0;
    if (i>=2) {
        NSLog(@"满足条件");
        self.finished = YES;
    }
    i++;
}

//这是一个任意任务
-(void)anyTask{
    NSLog(@"this is anyTask");
}

@end
